package org.wabson.alfresco.translations;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

/**
 * Servlet to provide downloads of message bundle JAR files contained in the class path.
 * 
 * @author wabson
 */
public class DownloadBundleServlet extends HttpServlet
{

    /**
     * 
     */
    private static final long serialVersionUID = 3233217361849983679L;
    private static final String BASE_PACKAGE = "/alfresco/bundles";
    public static final String BLOB_KEY_PARAM_NAME = "k";
    public static final String JAR_FILE_PARAM_NAME = "j";
    public static final String FILE_PATH_PARAM_NAME = "f";

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException
    {
    	WebApplicationContext springContext = WebApplicationContextUtils
    			.getRequiredWebApplicationContext(getServletContext());
    	
        String filePath = req.getParameter(FILE_PATH_PARAM_NAME);
        
        if (filePath != null && !filePath.equals("") && 
                !filePath.endsWith(".properties") && !filePath.endsWith(".txt"))
        {
            throw new ServletException("File name must end with .properties or .txt suffix if specified");
        }
        
        if (req.getParameter(JAR_FILE_PARAM_NAME) != null && !req.getParameter(JAR_FILE_PARAM_NAME).equals(""))
        {
            String jarName = req.getParameter(JAR_FILE_PARAM_NAME);
            
            if (!jarName.endsWith(".jar"))
            {
                throw new ServletException("Bundle name must end with .jar suffix");
            }
            
            if (filePath == null || filePath.equals(""))
            {
                ServletOutputStream os = resp.getOutputStream();

                InputStream is = null;
                
                try
                {
					JarBundleLoader loader = ((BundleLoaderFactory) springContext.getBean("bundle-loader-factory")).createLoader(BASE_PACKAGE + "/" + jarName, "");
					is = loader.getInputStream();
	                
	                // Set response headers
	                resp.setContentType("application/zip");
	                resp.setHeader("Content-disposition", "attachment; filename=" + loader.getFileName());
	                
                    byte[] bytes = new byte[2048];
                    int bytesRead;
                    while ((bytesRead = is.read(bytes, 0, bytes.length)) != -1)
                    {
                        os.write(bytes, 0, bytesRead);
                    }
				}
                catch (BundleLoadingException e)
                {
                    throw new ServletException("Jar file " + jarName + " could not be found", e);
				}
                catch (IOException e)
                {
                    e.printStackTrace();
                }
                finally
                {
                    if (is != null)
                        is.close();
                    if (os != null)
                        os.close();
                }
            }
            else
            {
                try
                {
                    BundleLoader loader = ((BundleLoaderFactory) springContext.getBean("bundle-loader-factory")).createLoader(BASE_PACKAGE + "/" + jarName, "");
                    MessageBundle mb = loader.load(filePath);
                    resp.setContentType("text/plain");
                    PrintWriter out = resp.getWriter();
                    for (String line : mb.getLines())
                    {
                        out.println(line);
                    }
                }
                catch (BundleLoadingException e)
                {
                    throw new ServletException("Unable to load message bundle", e);
                }
            }
        }
        else if (req.getParameter(BLOB_KEY_PARAM_NAME) != null && !req.getParameter(BLOB_KEY_PARAM_NAME).equals(""))
        {
            String blobKeyName = req.getParameter(BLOB_KEY_PARAM_NAME);
            
            if (filePath == null || filePath.equals(""))
            {
                ServletOutputStream os = resp.getOutputStream();

                InputStream is = null;
                
                try
                {
					JarBundleLoader loader = ((BundleLoaderFactory) springContext.getBean("langpack-loader-factory")).createLoader(blobKeyName, "");
					is = loader.getInputStream();
	                
	                // Set response headers
	                resp.setContentType("application/zip");
	                resp.setHeader("Content-disposition", "attachment; filename=" + loader.getFileName());
	                
                    byte[] bytes = new byte[2048];
                    int bytesRead;
                    while ((bytesRead = is.read(bytes, 0, bytes.length)) != -1)
                    {
                        os.write(bytes, 0, bytesRead);
                    }
				}
                catch (BundleLoadingException e)
                {
                    throw new ServletException("Blob " + blobKeyName + " could not be found", e);
				}
                catch (IOException e)
                {
                    e.printStackTrace();
                }
                finally
                {
                    if (is != null)
                        is.close();
                    if (os != null)
                        os.close();
                }
            }
            else
            {
                try
                {
                    BundleLoader loader = ((BundleLoaderFactory) springContext.getBean("langpack-loader-factory")).createLoader(blobKeyName, "");
                    MessageBundle mb = loader.load(filePath);
                    resp.setContentType("text/plain");
                    PrintWriter out = resp.getWriter();
                    for (String line : mb.getLines())
                    {
                        out.println(line);
                    }
                }
                catch (BundleLoadingException e)
                {
                    throw new ServletException("Unable to load message bundle", e);
                }
            }
        }
        else
        {
            throw new ServletException("Must specify either a JAR file or blob key");
        }

    }

}
